package prodcon;

public class CircularBuffer4  implements Buffer {
	private static final int MAX_SIZE = 8;
	private int base = 0;
	private int[] circBuffer = new int[MAX_SIZE];
	private int size = 0;
	
	public int getValueFromBuffer() {
		int index = base;
		synchronized(this) {
			base = (base + 1) % MAX_SIZE;
			size--;
			return circBuffer[index];
		}
	}

	public void putValueIntoBuffer(int value) {
		int index;
		synchronized(this) {
			index = (base + size) % MAX_SIZE;
			size++;
			circBuffer[index] = value;
		}
	}
	
	private boolean bufferIsEmpty() {
		return (size == 0);
	}

	private boolean bufferIsFull() {
		return (size == MAX_SIZE);
	}
	
	public int get() throws InterruptedException {
		synchronized (this) {
			while (bufferIsEmpty()) {
				// wait releases the lock until it is ready to continue...
				this.wait();
				// ...then regains the lock before it continues!
			}
		}
		int ret = getValueFromBuffer();
		synchronized(this) {
			this.notify(); // notify a potentially waiting Producer
		}
		return ret;
	}

	public void put(int value) throws InterruptedException {
		synchronized (this) {
			while (bufferIsFull()) {
				// wait releases the lock until it is ready to continue...
				this.wait();
				// ...then regains the lock before it continues!
			}
		}
		putValueIntoBuffer(value);
		synchronized(this) {
			this.notify(); // notify a potentially waiting Consumer
		}
	}
}